/*****************************************************************************/
/*!	\file		PIS10Callbacks.c
 *	\brief		C Source code file for the YX-PIS Example
 *	\par		Dalian Yunxing Tech Co., Ltd.
 *
 *				Dalian, China
 *				Phone   : +86 (411) 8825 4852
 *				Email   : yx@yunxing.tech
 */
/*****************************************************************************/

#include <string.h>
#include <math.h>
#include "PIS10Callbacks.h"
#include "IEC61850Functions.h"
#include "LocalData.h"
#include "IEC61850API.h"
#include "PIS10CreateServerClient.h"
#include "PrintView.h"

IEC61850_CallbackReturnServiceErrorCode WriteCallbackHandler(void* userData, const void* dataMap, const IEC61850_DataAttributeData* newValue)
{
	IEC61850_CallbackReturnServiceErrorCode ErrorCode = IEC61850_CB_ERROR_NONE;
	IEC61850 iec61850 = GetMyServerClient();
	IEC61850_DataMapMode mode = IEC61850_GetDataMapMode(iec61850);
	if (mode == IEC61850_MAP_MODE_DAID) {
		const IEC61850_DataAttributeID* daid = (const IEC61850_DataAttributeID*)dataMap;
		if (daid && newValue && newValue->pvData) {
			if ((daid->field1 == 8) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0)) {
				S32 newVal = *((S32*)newValue->pvData);
				switch (daid->field5) {
				case 1:
					SetMaxNumRcd(newVal);
					break;
				case 2:
					SetOpMod(newVal);
					break;
				case 3:
					SetMemFull(newVal);
					break;
				}
				PrintServerFullView();
			}
		}
	} else if (mode == IEC61850_MAP_MODE_SADDR) {
		const char* sAddr = (const char*)dataMap;
		if (sAddr) {
			printf("sAddr = %s\n", sAddr);
		}
	} else if (mode == IEC61850_MAP_MODE_REFERENCE) {
		const char* ref = (const char*)dataMap;
		if (ref) {
			printf("reference = %s\n", ref);
		}
	}

	return ErrorCode;
}

eCommandAddCause SelectCallbackHandler(void* userData, const void* dataMap, const IEC61850_DataAttributeData* selectValue, const IEC61850_CommandParameter* selectParameters)
{
	eCommandAddCause addCause = IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE;
	return addCause;
}

eCommandAddCause SelectTimeoutHandler(void* userData, const void* dataMap, const IEC61850_DataAttributeData* selectValue)
{
	eCommandAddCause addCause = IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE;
	IEC61850 iec61850 = GetMyServerClient();
	IEC61850_DataMapMode mode = IEC61850_GetDataMapMode(iec61850);

	if (mode == IEC61850_MAP_MODE_DAID) {
		IEC61850_DataAttributeID* daid = (IEC61850_DataAttributeID*)dataMap;
		printf("daid: ");
		IEC61850_PrintDataAttributeID(daid);
	} else if (mode == IEC61850_MAP_MODE_SADDR) {
		const char* sAddr = (const char*)dataMap;
		if (sAddr) {
			printf("sAddr: %s", sAddr);
		}
	} else if (mode == IEC61850_MAP_MODE_REFERENCE) {
		const char* ref = (const char*)dataMap;
		if (ref) {
			printf("reference: %s", ref);
		}
	}
	printf("\n");

	return addCause;
}

eCommandAddCause OperativeTestCallbackHandler(void* userData, const void* dataMap, const IEC61850_CommandParameter* operativeTestParameters)
{
	eCommandAddCause addCause = IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE;
	return addCause;
}

eCommandAddCause OperateCallbackHandler(void* userData, const void* dataMap, const IEC61850_DataAttributeData* operateValue, const IEC61850_CommandParameter* operateParameters)
{
	eCommandAddCause addCause = IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE;

	IEC61850_ErrorCode result = S_OK;
	IEC61850_DataAttributeData StValDAData = { 0 };
	IEC61850 iec61850 = GetMyServerClient();
	S8 dbPosValue = DBPOS_OFF;
	Boolean boolValue = FALSE;

	/* ==== IMPORTANT NOTE ====
	 * We update the stVal related to the control in this callback
	 * This stVal should represent the hardware state and should be
	 * updated only when the hardware state changes
	 *
	 * This example does not have hardware attached so the stVal
	 * is updated when the operate happens to "emulate" a hardware change
	 * ========================
	 */

	IEC61850_DataMapMode mode = IEC61850_GetDataMapMode(iec61850);
	if (mode == IEC61850_MAP_MODE_DAID) {
		IEC61850_DataAttributeID* daid = (IEC61850_DataAttributeID*)dataMap;

		if ((daid->field1 == 1) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 0)) { /* CSWI Pos */
			/* Setup the Data Attribute Data Struct */
			StValDAData.bitLength = IEC61850_DBPOS_BITSIZE;	// set the size of the data in bits
			StValDAData.type = IEC61850_DATATYPE_DBPOS;	// set the type of the data
			StValDAData.pvData = &dbPosValue;	// set a pointer to the data

			/* Set the DBPos Value based on the Operate ctlVal to emulate hardware change */
			if ((*((S8*)operateValue->pvData)) == FALSE) {
				dbPosValue = DBPOS_OFF;
			} else {
				dbPosValue = DBPOS_ON;
			}

			/* Perform the Update */
			result = IEC61850_Update(iec61850, daid, &StValDAData, 1);	// count of 1 as only 1 element is being updated
			if (result == S_OK) {
				/* If the Update Succeeded Update the local value for the gui*/
				SetCSWIStVal((eDbPosValues)dbPosValue);
				PrintServerFullView();	/* Redraw Server GUI */
			} else {
				/* If the Update failed alert the user */
				char strError[SIZE_OF_ERROR_STRING] = { 0 };
				snprintf(strError, SIZE_OF_ERROR_STRING, "CSWI stVal: Update failed:(%i) %s\n", result, IEC61850_ErrorString(result));
				SetErrorString(strError, SIZE_OF_ERROR_STRING);
			}
		} else if ((daid->field1 == 2) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0)) { /* GGIO SPCSO1~SPCSO4 */
			/* Setup the Data Attribute Data Struct */
			StValDAData.bitLength = sizeof(boolValue) * 8; //Set the size of the sgData in bits
			StValDAData.type = IEC61850_DATATYPE_BOOLEAN;	// set the type of the data
			StValDAData.pvData = &boolValue;	// set a pointer to the data

			/* Set the Boolean value based on the Operate ctlVal to emulate hardware change */
			boolValue = (*((S8*)operateValue->pvData));

			/* Perform the Update */
			result = IEC61850_Update(iec61850, daid, &StValDAData, 1);	// count of 1 as only 1 element is being updated

			if (result == S_OK) {
				/* If the Update Succeeded Update the local value for the gui*/
				SetGGIOStVal(boolValue, daid->field5);
				PrintServerFullView();	/* Redraw Server GUI */
			} else {
				/* If the Update failed alert the user */
				char strError[SIZE_OF_ERROR_STRING] = { 0 };
				snprintf(strError, SIZE_OF_ERROR_STRING, "GGIO stVal: Update failed:(%i) %s\n", result, IEC61850_ErrorString(result));
				SetErrorString(strError, SIZE_OF_ERROR_STRING);
				PrintServerFullView();	/* Redraw Server GUI */
			}
		}
	} else if (mode == IEC61850_MAP_MODE_SADDR) {
		const char* addr = (const char*)dataMap;
		if (addr) {
			printf("sAddr: %s", addr);
			printf("\n");
		}
	} else { // IEC61850_MAP_MODE_REFERENCE
		const char* reference = (const char*)dataMap;
		if (reference) {
			printf("reference: %s", reference);
			printf("\n");
		}
	}

	return addCause;
}

eCommandAddCause CancelCallbackHandler(void* userData, const void* dataMap, const IEC61850_CommandParameter* cancelParameters)
{
	eCommandAddCause addCause = IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE;
	return addCause;
}

eCommandAddCause CommandTerminationCallback(void* userData, const void* dataMap, const ControlResult* controlResult)
{
	eCommandAddCause addCause = IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE;
	return addCause;
}

void UpdateCallbackHandler(void* userData, const void* dataMap, const IEC61850_DataAttributeData* newValue)
{
	IEC61850_DataAttributeID* daid = (IEC61850_DataAttributeID*)dataMap; // cast dataMap to a daid type

	S32 int32LocalVal = 0; // temporary variable to hold the current local value
	S32 int32NewVal = 0; // temporary variable to hold the new value
	eDbPosValues dbPosLocalValue = DBPOS_OFF;
	eDbPosValues dbPosNewValue = DBPOS_OFF;
	IEC61850DbPosValue dbPoseNetworkValue = IEC61850_DB_POS_OFF;	// the dbpos value from the callback uses IEC61850DbPosValue (hex values)

	Boolean boolLocalValue = FALSE;
	Boolean boolNewValue = FALSE;
	CrvPts crvPtsLocalValue = { 0 };
	Float32 XYValNewValue = 0;

	Float32 f32LocalValue = 0;
	Float32 f32NewValue = 0;

	if ((daid->field1 == 1) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 0)) { /* CSWI Pos.stVal */
		dbPosLocalValue = GetCSWIStVal();
		dbPoseNetworkValue = (IEC61850DbPosValue)(*((U8*)newValue->pvData));

		/* convert the dbpos values returned by stack from IEC61850DbPosValue to eDbPosValues */
		switch (dbPoseNetworkValue) {
		case IEC61850_DB_POS_OFF:
			dbPosNewValue = DBPOS_INTERMEDIATE;
			break;
		case IEC61850_DB_POS_FALSE:
			dbPosNewValue = DBPOS_OFF;
			break;
		case IEC61850_DB_POS_TRUE:
			dbPosNewValue = DBPOS_ON;
			break;
		case IEC61850_DB_POS_INVALID:
			dbPosNewValue = DBPOS_BAD;
			break;
		}

		/* check whether the value has changed, then update the local value and GUI printing */
		if (dbPosLocalValue != dbPosNewValue) {
			SetCSWIStVal(dbPosNewValue);

			// the non NULL userData was set by the server subscriber,
			// here we use it to distinguish the instance role is a client or server-subscriber
			if (userData) {
				SetErrorString("", 0);
				PrintServerSubscriptionFullView();
			} else {
				PrintClientFullView();
			}
		}
	} else if ((daid->field1 == 2) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0)) { /* GGIO SPCSO1~SPCSO4 stVal */
		boolLocalValue = GetGGIOStVal(daid->field5);
		boolNewValue = (*((S8*)newValue->pvData));

		/* check whether the value has changed, then update the local value and GUI printing */
		if ((((boolLocalValue == FALSE) && (boolNewValue == FALSE)) || ((boolLocalValue != FALSE) && (boolNewValue != FALSE))) == FALSE) {
			SetGGIOStVal(boolNewValue, daid->field5);
			if (userData) { //if user sgData is set than this is a server subscription callback
				SetErrorString("", 0);
				PrintServerSubscriptionFullView();
			} else {
				PrintClientFullView();
			}
		}
	} else if ((daid->field1 == 3) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 0)) { /* MMXU A.phsA.cVal.mag.i */
		int32LocalVal = GetMMXUPhsAMagi();
		int32NewVal = (*((S32*)newValue->pvData));

		/* check whether the value has changed, then update the local value and GUI printing */
		if (int32LocalVal != int32NewVal) {
			SetMMXUPhsAMagi(int32NewVal);
			PrintClientFullView();
		}
	} else if ((daid->field1 == 4) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 0)) { /* MMXU A.phsB.cVal.mag.i */
		int32LocalVal = GetMMXUPhsBMagi();
		int32NewVal = (*((S32*)newValue->pvData));

		/* check whether the value has changed, then update the local value and GUI printing */
		if (int32LocalVal != int32NewVal) {
			SetMMXUPhsBMagi(int32NewVal);
			PrintClientFullView();
		}
	} else if ((daid->field1 == 5) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 0)) { /* MMXU A.phsC.cVal.mag.i */
		int32LocalVal = GetMMXUPhsCMagi();
		int32NewVal = (*((S32*)newValue->pvData));

		/* check whether the value has changed, then update the local value and GUI printing */
		if (int32LocalVal != int32NewVal) {
			SetMMXUPhsCMagi(int32NewVal);
			PrintClientFullView();
		}
	} else if ((daid->field1 == 6) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 0)) { /* PDIF TmASt.crvPts */
		if (newValue->arrayIndex == -1) { // if it is the entire array
			IEC61850_DataAttributeData* ptArrayXValElement = NULL;
			IEC61850_DataAttributeData* ptArrayYValElement = NULL;
			S8 LocalIndex = 0;
			Boolean dataHasChanged = FALSE;

			/* loop through each pair of the array elements */
			int i = 0;
			for (i = 0; i < ((int)newValue->bitLength); i = i + 2) {
				LocalIndex = i / 2;
				crvPtsLocalValue = GetPDIFCrvPts(LocalIndex);
				ptArrayXValElement = ((IEC61850_DataAttributeData*)newValue->pvData) + i; // Get the xVal element
				ptArrayYValElement = ((IEC61850_DataAttributeData*)newValue->pvData) + (i + 1); // Get the yVal element

				/* check whether the xVal has a new value, then update the local xVal value and mark the data change flag */
				XYValNewValue = (*(Float32*)ptArrayXValElement->pvData);
				/* Floating points are never 100% accurate on systems so we use the difference method to determine if it is close enough */
				if (fabs(crvPtsLocalValue.xVal - XYValNewValue) > 0.00000001) {
					crvPtsLocalValue.xVal = XYValNewValue;
					SetPDIFCrvPts(LocalIndex, crvPtsLocalValue);
					dataHasChanged = TRUE;
				}

				/* check whether the yVal has a new value, then update the local yVal value and mark the data change flag */
				XYValNewValue = (*(Float32*)ptArrayYValElement->pvData);
				/* Floating points are never 100% accurate on systems so we use the difference method to determine if it is close enough */
				if (fabs(crvPtsLocalValue.yVal - XYValNewValue) > 0.00000001) {
					crvPtsLocalValue.yVal = XYValNewValue;
					SetPDIFCrvPts(LocalIndex, crvPtsLocalValue);
					dataHasChanged = TRUE;
				}
			}

			/* if data change flag is marked, then update the GUI */
			if (dataHasChanged != FALSE) {
				PrintClientFullView();
			}
		}
	} else if ((daid->field1 == 7) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 0)) {	/* TTNS TnsSv1.instMag.f */
		f32LocalValue = GetTTNSTnsSv1Magf();
		f32NewValue = (*((Float32*)newValue->pvData));

		/* check whether the value has changed, then update the local value and GUI printing */
		if (f32LocalValue != f32NewValue) {
			SetTTNSTnsSv1Magf(f32NewValue);
			PrintClientFullView();
		}
	} else if ((daid->field1 == 7) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 1)) {	/* TTNS TnsSv2.instMag.f */
		f32LocalValue = GetTTNSTnsSv2Magf();
		f32NewValue = (*((Float32*)newValue->pvData));

		/* check whether the value has changed, then update the local value and GUI printing */
		if (f32LocalValue != f32NewValue) {
			SetTTNSTnsSv2Magf(f32NewValue);
			PrintClientFullView();
		}
	} else if ((daid->field1 == 7) && (daid->field2 == 0) && (daid->field3 == 0) && (daid->field4 == 0) && (daid->field5 == 2)) {	/* TTNS TnsSv3.instMag.f */
		f32LocalValue = GetTTNSTnsSv3Magf();
		f32NewValue = (*((Float32*)newValue->pvData));

		/* check whether the value has changed, then update the local value and GUI printing */
		if (f32LocalValue != f32NewValue) {
			SetTTNSTnsSv3Magf(f32NewValue);
			PrintClientFullView();
		}
	}
}

void FCDAUpdateCallbackHandler(void* userData, const void* dataMap, const IEC61850_DataAttributeData* newValue, unsigned int dataNum)
{
	unsigned int i = 0;
	printf("\n");
	printf("data quantity: %u\n", dataNum);
	printf("data list:\n");
	for (i = 0; i < dataNum; i++) {
		printf("  data[%u]:\n", i);
		PrintDAVal((IEC61850_DataAttributeData*)&newValue[i], 2);
		printf("\n");
	}
}

void QuestionableCallbackHandler(void* userData, const IEC61850_DataAttributeID* daid)
{
	// the non NULL userData was set by the server subscriber,
	// here we use it to ensure the instance role is the server-subscriber
	if (userData) {
		/* alert user that the GOOSE publishing has exceeded TAL */
		char strError[SIZE_OF_ERROR_STRING] = { 0 };
		snprintf(strError, SIZE_OF_ERROR_STRING, "GOOSE Data point is questionable - DAID: %u, %u, %u, %u, %u", daid->field1, daid->field2, daid->field3, daid->field4, daid->field5);
		SetErrorString(strError, SIZE_OF_ERROR_STRING);

		PrintServerSubscriptionFullView(); // update server subscriber screen
	}
}

Boolean FilePathResolveCallback(int serviceCode, const char* path, char* out, int length)
{
	int len = 0;
	//if (serviceCode == SC_GetFile) {
	// // ignore
	//}

	if (!path || !out || !length) {
		return FALSE;
	}

	len = (int)strlen(path);
	if (!len || len > length) {
		return FALSE;
	}
 
	{
		const char* temp = "/d:/tmp/";
		int len = (int)strlen(temp);
		strncpy(out, temp, len);
		out[len] = '\0';
	}

	//strncpy(out, path, len);
	//out[len] = '\0';
	return TRUE;
}

IEC61850_FileResponseCode FileCallbackHandler(void* userData, IEC61850_FileCallType fileCallType, tFileAttr* fileAttributes)
{
	IEC61850_FileResponseCode responseCode = IEC61850_FILE_RESPONSE_ACCEPT;
	U32 fileIndex = 0;

	switch (fileCallType) {
	case IEC61850_FILE_CALL_READ:
		// printf("Open file: %s\n", fileAttributes->primaryFile.fileName);
		break;
	case IEC61850_FILE_CALL_GET_ATTRIBUTES:
		// printf("Read file or directory attributes of '%s'\n", fileAttributes->primaryFile.fileName);
		if (strcmp(fileAttributes->primaryFile.fileName, "MySecretDirectory") == 0) {
			responseCode = IEC61850_FILE_RESPONSE_ACCESS_DENIED;
		}
		break;
	case IEC61850_FILE_CALL_DELETE:
		// set the responseCode as IEC61850_FILE_RESPONSE_ACCEPT to allow the file deletion,
		// or set the responseCode as IEC61850_FILE_RESPONSE_ACCESS_DENIED to reject the file deletion.
		// responseCode = IEC61850_FILE_RESPONSE_ACCESS_DENIED;

		if (responseCode == IEC61850_FILE_RESPONSE_ACCESS_DENIED) {
			// printf("DeleteFile '%s' denied\n", fileAttributes->primaryFile.fileName);
		} else if (responseCode == IEC61850_FILE_RESPONSE_ACCEPT) {
			// printf("DeleteFile '%s' allowed \n", fileAttributes->primaryFile.fileName);
		} else {
			// printf("DeleteFile '%s' - File does not exist \n", fileAttributes->primaryFile.fileName);
		}

		break;
	case IEC61850_FILE_CALL_SET_FILE:
		// printf("SetFile requested. file to be written: '%s', write size: %u\n", fileAttributes->primaryFile.fileName, fileAttributes->primaryFile.fileSize);
		break;
	case IEC61850_FILE_CALL_SET_FILE_COMPLETE:
		// printf("SetFile '%s' completed. last write size: %u\n", fileAttributes->primaryFile.fileName, fileAttributes->primaryFile.fileSize);
		break;
	case IEC61850_FILE_CALL_SET_FILE_FAIL:
		// printf("SetFile request failed. file to be written: '%s', write size: %u\n", fileAttributes->primaryFile.fileName, fileAttributes->primaryFile.fileSize);
		break;
	default:
		// printf("Unknown file call type %d\n", fileCallType);
		break;
	}
	return responseCode;
}

eServiceError SettingGroupCallback(void* userData, IEC61850_SettingGroup_Operation sgOper, void* sgParam)
{
	eServiceError serviceError = SERVICE_ERROR_NO_ERROR;
	// this is a setting group callback function example.
	return serviceError;	// delete this line to run the example code below.

	static S32 s_sg_val = 0;
	if (sgParam) {
		switch (sgOper) {
			case SG_SELECT_ACTIVE:
			case SG_SELECT_EDIT:
			{
				SGCallback_Select* selectParam = sgParam;
				break;
			}
			case SG_CONFIRM_EDIT:
			{
				char* reference = sgParam;
				break;
			}
			case SG_GET_VALUE:
			{
				SGCallback_Data* sgData = sgParam;
				Boolean isSE = TRUE;
				if (strncmp(sgData->fc, "SG", 2) == 0) {
					isSE = FALSE;
				}

				if (sgData->reference) {
					if (strncmp(sgData->reference, "ServerIEDExample/IARC0.MaxNumRcd.setVal", OBJECT_REFERENCE_STRING_LEN) == 0) {
						if (isSE) {
							if (sgData->type == IEC61850_DATATYPE_INT32) {
								s_sg_val = 123;
								memset(sgData->data, 0, BITS_TO_BYTES(sgData->size));
								memcpy(sgData->data, &s_sg_val, sizeof(s_sg_val));
							}
						} else {
							if (sgData->type == IEC61850_DATATYPE_INT32) {
								s_sg_val = 456;
								memset(sgData->data, 0, BITS_TO_BYTES(sgData->size));
								memcpy(sgData->data, &s_sg_val, sizeof(s_sg_val));
							}
						}
					}
				}
				break;
			}
			case SG_SET_VALUE:
			{
				SGCallback_Data* sgData = sgParam;
				if (sgData->reference) {
					if (strncmp(sgData->reference, "ServerIEDExample/IARC0.MaxNumRcd.setVal", OBJECT_REFERENCE_STRING_LEN) == 0) {
						if (sgData->type == IEC61850_DATATYPE_INT32) {
							s_sg_val = 456;
							memset(sgData->data, 0, BITS_TO_BYTES(sgData->size));
							memcpy(sgData->data, &s_sg_val, sizeof(s_sg_val));
							// printf("set %s is %d\n", sgData->reference, *((S32*)sgData->data));
						}
					}
				}
				break;
			}
			case SG_GET_SGCB:
			{
				char* reference = sgParam;
				break;
			}
		}
	}
	return serviceError;
}

void ConnectionStatusCallbackHandler(void* userData, IEC61850_ServerStatusArray statusArray)
{
	int index = 0;
	char* connectStatus;

	for (index = 0; index < statusArray.serverStatusArraySize; index++) {
		IEC61850_ServerStatus* status = &statusArray.serverStatusArray[index];
		printf("IED Name:%s\n", status->iedName);
		printf("IP Address:%s\n", status->ipAddress);
		printf("OS error code:%d\n", status->OSErrorCode);

		switch (status->isConnected) {
		case SERVER_STATUS_UNKNOWN:
			connectStatus = "UNKNOWN";
			break;
		case SERVER_STATUS_CONNECTED:
			connectStatus = "CONNECTED";
			break;
		case SERVER_STATUS_DISCONNECTED:
			connectStatus = "DISCONNECTED";
			break;
		case SERVER_STATUS_CONNECTING:
			connectStatus = "CONNECTING";
			break;
		case SERVER_STATUS_DISCONNECTING:
			connectStatus = "DISCONNECTING";
			break;
		}
		printf("Connect status:%s\n", connectStatus);
	}
}

void RpcCallTest(RpcData* reqData, RpcData* respData)
{
	static U32 respVal = 0;
	respData->eDataType = DATA_TYPE_INT32U;
	respData->bitSize = 32;
	respData->pvData = &respVal;

	U32 reqVal = *((U32*)reqData->pvData);
	respVal = reqVal * 10 + 9;
}